package com.wf.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author wufei
 * @date 2018/3/20/020 12:01
 */
public class RedisLock {

    public String getLock(String key) {
        try {
            Jedis jedis = RedisManager.getJedis();
            String s = UUID.randomUUID().toString();

            long end = System.currentTimeMillis() + 50000;
            while (System.currentTimeMillis() < end) {
                end++;
                if (jedis.setnx(key, s) == 1) {
                    jedis.expire(key, 2);
                    return s;
                }
                Thread.sleep(1000);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean releaseLock(String key, String value) {
        try {
            Jedis jedis = RedisManager.getJedis();
            while (true) {
                if (value.equals(jedis.get(key))) {
                    Transaction multi = jedis.multi();
                    multi.del(key);
                    List<Object> exec = multi.exec();
                    if (exec == null) {
                        continue;
                    }
                    return true;
                }
                break;

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) {
        RedisLock redisLock = new RedisLock();
        redisLock.getLock("my:lock");

        ExecutorService service = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            service.execute(() -> {
                String lock = redisLock.getLock("my:lock");
                try {
                    Thread.sleep(100);
                    System.out.println(lock + " | " + Thread.currentThread().getId());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean b = redisLock.releaseLock("my:lock", lock);
                System.out.println(b + "->" + lock + " | " + Thread.currentThread().getId());
            });
        }

        System.out.println("");


    }

}
